#!/usr/bin/env python
#-*- Coding: UTF-8 -*-

#from gstxmlrpc import *
import sys, time, threading
from twisted.internet import reactor
from twisted.web import server
from twisted.web import xmlrpc
from twisted.internet import defer
import os
import pygst,gobject
pygst.require("0.10")
import gst

# This module is standard in Python 2.2, otherwise get it from
#   http://www.pythonware.com/products/xmlrpc/
import xmlrpclib

class GstServer(xmlrpc.XMLRPC):
    media =[ ["ETV", "udp://239.3.1.1:1234"],
            ["Kanal 2", "udp://239.3.1.2:1234"],
            ["TV3", "udp://239.3.1.3:1234"],
            ["Neljas","udp://239.3.1.13:1234"],
            ["YLE 2", "udp://239.3.1.6:1234"],
            #["Kanal 11","udp://239.3.2.2:1234"],
            ["Fox Crime","udp://239.3.1.7:1234"],
            ["BBC Prime","udp://239.3.5.3:1234"],
            ["VH-1","udp://239.3.4.5:1234"],
            ["VH-1 Classic","udp://239.9.10.2:1234"],
            ["ETV2","udp://239.9.14.2:1234"]
        ]
    port = 1234
    current = 0
        
    def xmlrpc_play(self, file):
        if file and file != "":
            self.player.set_state(gst.STATE_NULL)
            self.source.set_property("uri",file)
        elif len(self.media)==0:
            return "Nothing to play"
        else:
            print self.media[self.current][1]
            self.source.set_property("uri",self.media[self.current][1])
        self.player.set_state(gst.STATE_PLAYING)
        
    def xmlrpc_state(self):
        old,new,pending = self.player.get_state()
        if new == gst.STATE_PLAYING:
            return 1
            
        return 0
        
    def xmlrpc_stop(self):
        self.player.set_state(gst.STATE_NULL)

    def xmlrpc_port(self):
        return self.port
        
    def xmlrpc_prev(self):
        self.current -=1 
        if self.current < 0:
            self.current = len(self.media) -1
        self.xmlrpc_stop()
        self.xmlrpc_play(None)

    def xmlrpc_next(self):
        self.current +=1 
        if self.current > len(self.media)-1:
            self.current = 0
        self.xmlrpc_stop()
        self.xmlrpc_play(None)
        
    def xmlrpc_title(self):
        return self.media[self.current][0]
        
    ''' Let client manage files
    def xmlrpc_load(self, file):
        f = fopen(file,"r")
        while True:
            line = f.readline()
            if not line: break
            media.append(line)
        f.close()
        
    def xmlrpc_add(self,file):
        print "Added %s"%file
        self.media.append(file)
        return "Added %s"%file
    '''

    def xmlrpc_list(self):
        return self.media
    
    def __init__(self):
        xmlrpc.XMLRPC.__init__(self,allowNone=True)
        self.paused = False
        self.player = gst.Pipeline("player")
        self.source = gst.element_factory_make("udpsrc", "data-source")
        #source.set_property("uri","")

        #self.queue0 = gst.element_factory_make("queue", "queue0")
        
        self.tcpsink = gst.element_factory_make("tcpserversink", "tcp-output")
        self.tcpsink.set_property("host","0.0.0.0")
        self.tcpsink.set_property("port",self.port)
        self.tcpsink.set_property("protocol",1)

        caps = gst.Caps("video/mpegts")
        filter = gst.element_factory_make("capsfilter", "filter")
        filter.set_property("caps", caps)

        self.player.add(self.source, filter, self.tcpsink)
        gst.element_link_many(self.source,filter, self.tcpsink)
        
        bus = self.player.get_bus()
        bus.add_signal_watch()
        bus.enable_sync_message_emission()
        bus.connect("message", self.on_message)
        #bus.connect("message::tag", self.on_tag_message)
        bus.connect("sync-message::element", self.on_sync_message)
        
        #self.player.set_state(gst.STATE_PLAYING)
        self.time_format = gst.Format(gst.FORMAT_TIME)

	def decoder_callback(self, decoder, pad, data):
		structure_name = pad.get_caps()[0].get_name()
		if structure_name.startswith("video"):
			fv_pad = self.fakev.get_pad("sink")
			pad.link(fv_pad)
		elif structure_name.startswith("audio"):
			fa_pad = self.fakea.get_pad("sink")
			pad.link(fa_pad)

    def demuxer_callback(self, demuxer, pad):
        if pad.get_property("template").name_template == "video_%02d":
            queuev_pad = self.queuev.get_pad("sink")
            pad.link(queuev_pad)
        elif pad.get_property("template").name_template == "audio_%02d":
            queuea_pad = self.queuea.get_pad("sink")
            pad.link(queuea_pad)
            
    def muxer_callback(self, muxer, pad):
        print pad.get_property("template").name_template
        #if pad.get_property("template").name_template == "video_%02d":
        #    queuev_pad = self.queuev.get_pad("sink")
        #    pad.link(queuev_pad)
        #elif pad.get_property("template").name_template == "audio_%02d":
        #    queuea_pad = self.queuea.get_pad("sink")
        #    pad.link(queuea_pad)
            
    def get_duration_ns(self):
        return self.player.query_duration(self.time_format, None)[0]
        
    def get_duration(self):
        return self.get_duration_ns() / 1000000000

    def on_message(self, bus, message):
        
        t = message.type
        #print "Message of",t
        if t == gst.MESSAGE_EOS:
            self.player.set_state(gst.STATE_NULL)
            print "EOS"
            
        elif t == gst.MESSAGE_ERROR:
            self.player.set_state(gst.STATE_NULL)
            err, debug = message.parse_error()
            print "Error: %s" % err, debug
            print message
                        
        #elif t == gst.MESSAGE_BUFFERING:
        #    self.statuses['buffer'] = "%d%%"%message.parse_buffering()
        #    self.set_status()
            
        elif t == gst.MESSAGE_STATE_CHANGED:
            old,new,pending = message.parse_state_changed()
            print "Server Gst State", new

    def on_sync_message(self, bus, message):
        if message.structure is None:
            return
        #message_name = message.structure.get_name()
        #if message_name == "prepare-xwindow-id":
            

    def convert_ns(self, time_int):
        time_int = time_int / 1000000000
        sec = time_int % 60
        min = time_int % 3600 / 60
        hour = time_int / 3600
        if hour == 0:
            return "%02d:%02d"%(min,sec)
        return "%d:%02d:%02d"%(hour,min,sec)
        


def run():
    r = GstServer()
    reactor.listenTCP(7080, server.Site(r))
    reactor.run(installSignalHandlers=0)
        
def main():
    
    #r = GstXMLRPC(gst)
    
    t = threading.Thread(target=run)
    t.setDaemon(True)
    t.start()
    
    # enter into a mainloop
    loop = gobject.MainLoop()
    gobject.threads_init()
    loop.run()
    



if __name__ == '__main__':
    main()
